<template>
  <el-dialog :model-value="modelValue" title="导入客户" width="760px" @update:model-value="$emit('update:modelValue', $event)">
    <div class="import-container">
      <el-alert type="info" show-icon :closable="false" class="mb-12" description="支持 CSV 文件（UTF-8 编码）。建议使用提供的模板导入。" />

      <div class="actions">
        <el-upload
          action=""
          :auto-upload="false"
          :show-file-list="false"
          accept=".csv"
          :on-change="onFileChange"
        >
          <el-button type="primary">选择CSV文件</el-button>
        </el-upload>
        <el-button @click="downloadTemplate">下载模板</el-button>
      </div>

      <div v-if="fileName" class="file-info">已选择文件：{{ fileName }}</div>

      <el-table v-if="previewRows.length" :data="previewRows" height="220" border stripe class="mt-12">
        <el-table-column v-for="col in previewColumns" :key="col" :prop="col" :label="col" min-width="120" />
      </el-table>

      <div v-if="previewRows.length" class="hint">预览前 {{ Math.min(previewRows.length, 10) }} 行（最多展示 10 行）。总计：{{ totalRows }} 行。</div>

      <el-divider />

      <div class="run-bar">
        <el-button type="success" :disabled="!rows.length || running" :loading="running" @click="startImport">开始导入</el-button>
        <span v-if="running || done">已成功 {{ successCount }} 条，失败 {{ failCount }} 条</span>
      </div>

      <el-alert v-if="errorMessage" type="error" :closable="false" class="mt-12" :title="errorMessage" />

      <el-table v-if="failRows.length" :data="failRows" height="180" border stripe class="mt-12">
        <el-table-column prop="__row__" label="#" width="60" />
        <el-table-column prop="__error__" label="错误" min-width="200" />
      </el-table>
    </div>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="$emit('update:modelValue', false)">关闭</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { customerApi } from '@/api/customerApi'

interface Props { modelValue: boolean }
const props = defineProps<Props>()
const emit = defineEmits<{ 'update:modelValue': [value: boolean]; 'success': [] }>()

const fileName = ref('')
const rows = ref<any[]>([])
const previewRows = ref<any[]>([])
const previewColumns = ref<string[]>([])
const totalRows = ref(0)
const running = ref(false)
const done = ref(false)
const successCount = ref(0)
const failCount = ref(0)
const failRows = ref<Array<{ __row__: number; __error__: string }>>([])
const errorMessage = ref('')

const onFileChange = async (file: any) => {
  try {
    resetState()
    fileName.value = file.name
    const text = await fileToText(file.raw || file)
    const parsed = parseCSV(text)
    totalRows.value = parsed.rows.length
    rows.value = parsed.rows
    previewColumns.value = parsed.columns
    previewRows.value = parsed.rows.slice(0, 10)
    if (!rows.value.length) {
      ElMessage.warning('CSV 文件没有数据')
    }
  } catch (e: any) {
    errorMessage.value = e?.message || '读取文件失败'
  }
}

function fileToText(file: File): Promise<string> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.onload = () => resolve(String(reader.result || ''))
    reader.onerror = () => reject(new Error('文件读取失败'))
    reader.readAsText(file, 'utf-8')
  })
}

// 简单 CSV 解析（支持逗号与双引号转义）
function parseCSV(text: string): { columns: string[]; rows: any[] } {
  const lines = text.replace(/\r\n/g, '\n').replace(/\r/g, '\n').split('\n').filter(l => l.trim().length > 0)
  if (!lines.length) return { columns: [], rows: [] }
  const columns = splitCSVLine(lines[0])
  const rows = lines.slice(1).map((line) => {
    const cells = splitCSVLine(line)
    const row: any = {}
    columns.forEach((c, i) => { row[c] = cells[i] ?? '' })
    return row
  })
  return { columns, rows }
}

function splitCSVLine(line: string): string[] {
  const result: string[] = []
  let current = ''
  let inQuotes = false
  for (let i = 0; i < line.length; i++) {
    const ch = line[i]
    if (ch === '"') {
      if (inQuotes && line[i + 1] === '"') { current += '"'; i++; continue }
      inQuotes = !inQuotes
      continue
    }
    if (ch === ',' && !inQuotes) { result.push(current.trim()); current = ''; continue }
    current += ch
  }
  result.push(current.trim())
  return result
}

function normalizeRow(raw: Record<string, string>) {
  // 映射列名（中英文/大小写）：
  const pick = (...names: string[]) => {
    for (const n of names) { const v = raw[n]; if (v !== undefined && v !== null && String(v).trim() !== '') return String(v).trim() }
    return ''
  }
  const toBool = (v: string) => ['1', 'true', '是', '启用', 'y', 'yes'].includes(String(v).toLowerCase())
  const toNumber = (v: string) => v === '' ? undefined : Number(v)
  const mapType = (v: string) => ({ '个人': 'Individual', 'enterprise': 'Enterprise', '企业': 'Enterprise', 'individual': 'Individual' } as any)[String(v).toLowerCase()] || v
  const mapStatus = (v: string) => ({ '活跃': 'Active', '非活跃': 'Inactive', '黑名单': 'Blacklisted' } as any)[v] || v

  return {
    customerName: pick('客户名称', 'CustomerName', 'name'),
    companyName: pick('公司名称', 'CompanyName'),
    customerType: mapType(pick('客户类型', 'CustomerType')) || 'Enterprise',
    customerStatus: mapStatus(pick('客户状态', 'CustomerStatus')) || 'Active',
    partnerLevelId: toNumber(pick('客户等级ID', 'CustomerLevelId', 'LevelId')),
    partnerCategoryId: toNumber(pick('客户类别ID', 'CustomerCategoryId', 'CategoryId')),
    salesRepresentativeId: toNumber(pick('销售代表ID', 'SalesRepresentativeId', 'PersonId')),
    industryId: toNumber(pick('所属行业ID', 'IndustryId')),
    businessNatureId: toNumber(pick('业务性质ID', 'BusinessNatureId', 'NatureId')),
    locationId: toNumber(pick('所在地区ID', 'LocationId')),
    creditLimit: Number(pick('信用额度', 'CreditLimit') || 0),
    creditRating: pick('信用等级', 'CreditRating') || 'A',
    paymentTerms: pick('付款条件', 'PaymentTerms') || '',
    unifiedSocialCreditCode: pick('统一社会信用代码', 'UnifiedSocialCreditCode', 'SOC'),
    phoneNumber: pick('电话', 'Phone', 'PhoneNumber'),
    faxNumber: pick('传真', 'Fax', 'FaxNumber'),
    email: pick('邮箱', 'Email'),
    website: pick('网址', 'Website'),
    companyAddress: pick('地址', 'CompanyAddress', 'Address'),
    remarks: pick('备注', 'Remarks'),
    isEnabled: toBool(pick('是否启用', 'IsEnabled')),    
  }
}

async function startImport() {
  if (!rows.value.length) return
  running.value = true
  done.value = false
  successCount.value = 0
  failCount.value = 0
  failRows.value = []
  errorMessage.value = ''

  const batchLimit = 5
  let cursor = 0
  const doNext = async () => {
    if (cursor >= rows.value.length) return
    const rowIndex = cursor
    cursor++
    const data = normalizeRow(rows.value[rowIndex])
    try {
      const res = await customerApi.createCustomer(data as any)
      if ((res as any)?.code === 200) {
        successCount.value++
      } else {
        failCount.value++
        failRows.value.push({ __row__: rowIndex + 2, __error__: (res as any)?.message || '失败' })
      }
    } catch (e: any) {
      failCount.value++
      failRows.value.push({ __row__: rowIndex + 2, __error__: e?.message || '失败' })
    }
    await doNext()
  }

  await Promise.all(Array.from({ length: Math.min(batchLimit, rows.value.length) }, () => doNext()))
  done.value = true
  if (failCount.value === 0) {
    ElMessage.success(`导入完成，成功 ${successCount.value} 条`)
    emit('success')
  } else {
    ElMessage.warning(`导入完成，成功 ${successCount.value} 条，失败 ${failCount.value} 条`)
  }
}

function resetState() {
  fileName.value = ''
  rows.value = []
  previewRows.value = []
  previewColumns.value = []
  totalRows.value = 0
  running.value = false
  done.value = false
  successCount.value = 0
  failCount.value = 0
  failRows.value = []
  errorMessage.value = ''
}

function downloadTemplate() {
  const headers = [
    '客户名称','公司名称','客户类型','客户状态','客户等级ID','客户类别ID','销售代表ID','所属行业ID','业务性质ID','所在地区ID','信用额度','信用等级','付款条件','统一社会信用代码','电话','传真','邮箱','网址','地址','备注','是否启用'
  ]
  const csv = headers.join(',') + '\n'
  const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = '客户导入模板.csv'
  a.click()
  URL.revokeObjectURL(url)
}
</script>

<style scoped>
.import-container { padding: 4px 6px; }
.mb-12 { margin-bottom: 12px; }
.mt-12 { margin-top: 12px; }
.actions { display: flex; gap: 10px; align-items: center; }
.file-info { margin-top: 8px; color: #606266; }
.hint { margin-top: 8px; color: #909399; font-size: 12px; }
.run-bar { display: flex; align-items: center; gap: 10px; }
.dialog-footer { text-align: right; }
</style> 